package com.ruoyi.web.cp.model;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.ruoyi.web.core.config.ConfigLoader;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Data
public class Game implements Comparable<Game> {
    private String gameId;
    private String teamA;
    private String teamB;
    private Date date;
    private String dateStr;
    private String league;
    private String result;
    private String memo;
    private List<Score> scores = new ArrayList<>();

    public Game() {
    }

    public Game(String teamA, String teamB, Date date, String league, String dateStr) {
        this.teamA = teamA;
        this.teamB = teamB;
        this.date = date;
        this.league = league;
        this.dateStr = dateStr;
    }

    public Game(String teamA, String teamB, Date date, String league, String dateStr, String result) {
        this.teamA = teamA;
        this.teamB = teamB;
        this.date = date;
        this.dateStr = dateStr;
        this.league = league;
        this.result = result;
    }

    @Override
    public int compareTo(Game other) {
        return Long.compare(other.getDate().getTime(), this.date.getTime()) * -1;
    }


    public void setScore(Score score) {
        this.scores.add(score);
    }

    @Data
    @NoArgsConstructor
    public static class Score {
        private String score;
        private String plv;
        private String plv2;
        private String plv3;
        private String plv4;
        private String fit;

        //波胆00赔率
        private String bdan00Plv;
        //双进赔率
        private String doublePlv;
        //增加大小盘、独赢胜平负、亚盘盘口赔率属性
        private String goalBigPlv;
        private String goalSmallPlv;
        private String goalDesc;

        //独赢胜平负
        private String winPlv;
        private String drawPlv;
        private String losePlv;

        //亚盘赔率
        private String asianBigPlv;
        private String asianSmallPlv;
        private String asianDesc;

        public Score(String score, String plv) {
            this.score = score;
            this.plv = plv;
        }

        public Score(String score, String plv, String plv2) {
            this.score = score;
            this.plv = plv;
            this.plv2 = plv2;
        }

        public Score(String score, String plv, String plv2, String plv3) {
            this.score = score;
            this.plv = plv;
            this.plv2 = plv2;
            this.plv3 = plv3;
        }
    }

    public void setDate(String dateStr) {
        this.dateStr = dateStr;
        this.date = DateUtil.parse(dateStr);
    }

    public static Map<String, String> getRmobDict() {
        ConfigLoader configLoader = SpringUtil.getBean("configLoader", ConfigLoader.class);
        List<String> strs = FileUtil.readLines(configLoader.getGamenamesPath() + "ob-gamename.txt", "utf8");
        return strs.stream().collect(HashMap::new, (m, v) -> {
            String[] split = v.split("=");
            m.put(split[0], split[1]);
        }, HashMap::putAll);
    }


    public static Map<String, String> getRmfbDict() {
        ConfigLoader configLoader = SpringUtil.getBean("configLoader", ConfigLoader.class);
        List<String> strs = FileUtil.readLines(configLoader.getGamenamesPath() + "fb-gamename.txt", "utf8");
        return strs.stream().collect(HashMap::new, (m, v) -> {
            String[] split = v.split("=");
            m.put(split[0], split[1]);
        }, HashMap::putAll);
    }

    public static Map<String, String> getAqobDict() {
        ConfigLoader configLoader = SpringUtil.getBean("configLoader", ConfigLoader.class);
        List<String> strs = FileUtil.readLines(configLoader.getGamenamesPath() + "aqob-gamename.txt", "utf8");
        return strs.stream().collect(HashMap::new, (m, v) -> {
            String[] split = v.split("=");
            m.put(split[0], split[1]);
        }, HashMap::putAll);
    }

    public static Map<String, String> getAqfbDict() {
        ConfigLoader configLoader = SpringUtil.getBean("configLoader", ConfigLoader.class);
        List<String> strs = FileUtil.readLines(configLoader.getGamenamesPath() + "aqfb-gamename.txt", "utf8");
        return strs.stream().collect(HashMap::new, (m, v) -> {
            String[] split = v.split("=");
            m.put(split[0], split[1]);
        }, HashMap::putAll);
    }

    public static String getGameName(String name, Map<String, String> dict, Map<String, String> dictOther) {
        if (dict.containsKey(name)) {
            name = dict.get(name);
        } else if (dictOther.containsKey(name)) {
            name = dictOther.get(name);
        }
        return name.replace(" ", "").trim();
    }

    public static List<Game> getGames(String path, String type) {
        Map<String, String> dict = new HashMap<>();
        Map<String, String> dictOther = new HashMap<>();
        switch (type) {
            case "ob":
                dict = getRmobDict();
                break;
            case "fb":
                dict = getRmfbDict();
                break;
            case "aqob":
                dict = getAqobDict();
                dictOther = getRmobDict();
                break;
            case "aqfb":
                dict = getAqfbDict();
                dictOther = getRmfbDict();
                break;
        }
        List<String> strs = FileUtil.readLines(path, "utf8");
        List<Game> games = new ArrayList<>();

        Game game = null;

        for (int i = 0; i < strs.size(); i++) {
            String str = strs.get(i);
            String[] split = str.split("\t");
            if (str.contains("2025-")) {
                game = new Game();
                games.add(game);
                List<Game.Score> scores = new ArrayList<>();
                game.setGameId(split[0]);
                game.setLeague(split[1]);
                game.setDate(split[2]);
                game.setTeamA(getGameName(split[3], dict, dictOther));
                game.setTeamB(getGameName(split[4], dict, dictOther));
                game.setScores(scores);
            } else {
                Game.Score score = null;
                if (split.length > 0) {
                    switch (split.length) {
                        case 2:
                            score = new Game.Score(split[0], split[1]);
                            break;
                        case 3:
                            score = new Game.Score(split[0], split[1], split[2]);
                            break;
                        case 4:
                            score = new Game.Score(split[0], split[1], split[2], split[3]);
                            break;
                        case 12:
                            score = new Game.Score();
                            score.setScore(split[0]);
                            score.setDoublePlv(split[1]);
                            score.setBdan00Plv(split[2]);
                            score.setGoalDesc(split[3]);
                            score.setGoalBigPlv(split[4]);
                            score.setGoalSmallPlv(split[5]);
                            score.setWinPlv(split[6]);
                            score.setDrawPlv(split[7]);
                            score.setLosePlv(split[8]);
                            score.setAsianDesc(split[9]);
                            score.setAsianBigPlv(split[10]);
                            score.setAsianSmallPlv(split[11]);
                            break;
                        default:
                            break;
                    }
                    game.getScores().add(score);
                }
            }
        }
        return games;
    }


    public static void calc(List<Game> rmGames, List<Game> otherGames, String type, String platform) {
        HashMap<Object, Game> dict = otherGames.stream().collect(HashMap::new, (m, v) -> {
            m.put(v.getTeamA() + v.getTeamB(), v);
        }, HashMap::putAll);

        for (Game game : rmGames) {
            String key = game.getTeamA() + game.getTeamB();
            if (dict.get(key) != null) {
                try {
                    List<Score> rmScore = game.getScores();
                    List<Score> otherScore = dict.get(key).getScores();
                    if (CollUtil.isEmpty(otherScore)) {
                        continue;
                    }
                    HashMap<Object, Score> dict2 = otherScore.stream().collect(HashMap::new, (m, v) -> {
                        m.put(v.getScore(), v);
                    }, HashMap::putAll);

                    for (Score score : rmScore) {
                        if ("accurate".equals(type)) {
                            switch (score.getScore()) {
                                case "0-0":
                                    score.setPlv2(dict2.get("X/XAnd0") != null ? dict2.get("X/XAnd0").getPlv() : null);
                                    break;
                                case "0-1":
                                    score.setPlv2(dict2.get("X/2And1") != null ? dict2.get("X/2And1").getPlv() : null);
                                    score.setPlv3(dict2.get("2/2And1") != null ? dict2.get("2/2And1").getPlv() : null);
                                    break;
                                case "0-2":
                                    score.setPlv2(dict2.get("X/2And2") != null ? dict2.get("X/2And2").getPlv() : null);
                                    score.setPlv3(dict2.get("2/2And2") != null ? dict2.get("2/2And2").getPlv() : null);
                                    break;
                                case "0-3":
                                    score.setPlv2(dict2.get("X/2And3") != null ? dict2.get("X/2And3").getPlv() : null);
                                    score.setPlv3(dict2.get("2/2And3") != null ? dict2.get("2/2And3").getPlv() : null);
                                    break;
                                case "1-0":
                                    score.setPlv2(dict2.get("X/1And1") != null ? dict2.get("X/1And1").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And1") != null ? dict2.get("1/1And1").getPlv() : null);
                                    break;
                                case "1-1":
                                    score.setPlv2(dict2.get("X/XAnd2") != null ? dict2.get("X/XAnd2").getPlv() : null);
                                    score.setPlv3(dict2.get("1/XAnd2") != null ? dict2.get("1/XAnd2").getPlv() : null);
                                    score.setPlv4(dict2.get("2/XAnd2") != null ? dict2.get("2/XAnd2").getPlv() : null);
                                    break;
                                case "1-2":
                                    score.setPlv2(dict2.get("X/2And3") != null ? dict2.get("X/2And3").getPlv() : null);
                                    score.setPlv3(dict2.get("1/2And3") != null ? dict2.get("1/2And3").getPlv() : null);
                                    score.setPlv4(dict2.get("2/2And3") != null ? dict2.get("2/2And3").getPlv() : null);
                                    break;
                                case "1-3":
                                    score.setPlv2(dict2.get("X/2And4") != null ? dict2.get("X/2And4").getPlv() : null);
                                    score.setPlv3(dict2.get("1/2And4") != null ? dict2.get("1/2And4").getPlv() : null);
                                    score.setPlv4(dict2.get("2/2And4") != null ? dict2.get("2/2And4").getPlv() : null);
                                    break;
                                case "2-0":
                                    score.setPlv2(dict2.get("X/1And2") != null ? dict2.get("X/1And2").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And2") != null ? dict2.get("1/1And2").getPlv() : null);
                                    break;
                                case "2-1":
                                    score.setPlv2(dict2.get("X/1And3") != null ? dict2.get("X/1And3").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And3") != null ? dict2.get("1/1And3").getPlv() : null);
                                    score.setPlv4(dict2.get("2/1And3") != null ? dict2.get("2/1And3").getPlv() : null);
                                    break;
                                case "2-2":
                                    score.setPlv2(dict2.get("X/XAnd4") != null ? dict2.get("X/XAnd4").getPlv() : null);
                                    score.setPlv3(dict2.get("1/XAnd4") != null ? dict2.get("1/XAnd4").getPlv() : null);
                                    score.setPlv4(dict2.get("2/XAnd4") != null ? dict2.get("2/XAnd4").getPlv() : null);
                                    break;
                                case "2-3":
                                    score.setPlv2(dict2.get("X/2And5+") != null ? dict2.get("X/2And5+").getPlv() : null);
                                    score.setPlv3(dict2.get("1/2And5+") != null ? dict2.get("1/2And5+").getPlv() : null);
                                    score.setPlv4(dict2.get("2/2And5+") != null ? dict2.get("2/2And5+").getPlv() : null);
                                    break;
                                case "3-0":
                                    score.setPlv2(dict2.get("X/1And2") != null ? dict2.get("X/1And3").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And2") != null ? dict2.get("1/1And3").getPlv() : null);
                                    break;
                                case "3-1":
                                    score.setPlv2(dict2.get("X/1And4") != null ? dict2.get("X/1And4").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And4") != null ? dict2.get("1/1And4").getPlv() : null);
                                    score.setPlv4(dict2.get("2/1And4") != null ? dict2.get("2/1And4").getPlv() : null);
                                    break;
                                case "3-2":
                                    score.setPlv2(dict2.get("X/1And5+") != null ? dict2.get("X/1And5+").getPlv() : null);
                                    score.setPlv3(dict2.get("1/1And5+") != null ? dict2.get("1/1And5+").getPlv() : null);
                                    score.setPlv4(dict2.get("2/1And5+") != null ? dict2.get("2/1And5+").getPlv() : null);
                                    break;
                                case "3-3":
                                    score.setPlv2(dict2.get("X/XAnd5+") != null ? dict2.get("X/XAnd5+").getPlv() : null);
                                    score.setPlv3(dict2.get("1/XAnd5+") != null ? dict2.get("1/XAnd5+").getPlv() : null);
                                    score.setPlv4(dict2.get("2/XAnd5+") != null ? dict2.get("2/XAnd5+").getPlv() : null);
                                    break;
                            }
                        } else if ("double".equals(type)) {
                            switch (score.getScore()) {
                                case "0-0":
                                    Score subScore = dict2.get("是");
                                    if (subScore != null) {
                                        score.setDoublePlv(subScore.getDoublePlv());
                                        score.setBdan00Plv(subScore.getBdan00Plv());
                                        score.setGoalDesc(subScore.getGoalDesc());
                                        score.setGoalBigPlv(subScore.getGoalBigPlv());
                                        score.setGoalSmallPlv(subScore.getGoalSmallPlv());
                                        score.setWinPlv(subScore.getWinPlv());
                                        score.setDrawPlv(subScore.getDrawPlv());
                                        score.setLosePlv(subScore.getLosePlv());
                                        score.setAsianDesc(subScore.getAsianDesc());
                                        score.setAsianBigPlv(subScore.getAsianBigPlv());
                                        score.setAsianSmallPlv(subScore.getAsianSmallPlv());
                                    }
                                    break;
                            }
                        } else if ("dy".equals(type)) {
                            if (score.getScore().equalsIgnoreCase("0-0")) {
                                score.setPlv2(dict2.get("X") != null ? dict2.get("X").getPlv() : null);
                            }
                        } else if ("dx2".equals(type)) {
                            if (score.getScore().equalsIgnoreCase("00:00-05:59")) {
                                List<String> list = Arrays.asList("1", "1.5", "1.5/2", "2", "2.5");
                                Iterator<Object> iterator = dict2.keySet().iterator();
                                while (iterator.hasNext()) {
                                    Object k = iterator.next();
                                    String v = dict2.get(k).getPlv();
                                    if (list.contains(k) && Double.parseDouble(v) <= 8D) {
                                        score.setGoalDesc(k + "");
                                        score.setBdan00Plv(dict2.get(k).getPlv());
                                    }
                                }
                            }
                        } else {
                            score.setPlv2(dict2.get(score.getScore()) != null ? dict2.get(score.getScore()).getPlv() : null);
                        }
                        if (!"jyb".equals(platform)) {
                            score.setFit(calcFit(platform, score.getPlv(), score.getPlv2(), score.getPlv3(), score.getPlv4()));
                        }
                    }
                    if (dict2.get("双进") != null) {
                        rmScore.add(new Score("双进", String.valueOf(dict2.get("双进").getPlv())));
                    }
                    if (dict2.get("大小") != null) {
                        rmScore.add(new Score("大小", String.valueOf(dict2.get("大小").getPlv())));
                    }
                    if (dict2.get("亚盘") != null) {
                        rmScore.add(new Score("亚盘", String.valueOf(dict2.get("亚盘").getPlv())));
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            } else {
                game.setMemo("未找到");
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(calcFit("hc", "22.58", "-999"));
    }

    public static String calcFit(String platform, String plv, String... plv2) {
        BigDecimal bd1 = new BigDecimal("1");
        BigDecimal bd10000 = new BigDecimal("10000");
        BigDecimal bd100 = new BigDecimal("100");
        BigDecimal bd9 = new BigDecimal("0.9");
        BigDecimal bd95 = new BigDecimal("0.95");
        BigDecimal bd92 = new BigDecimal("0.92");
        BigDecimal plvBd = new BigDecimal(plv);
        BigDecimal bd = null;
        switch (platform) {
            case "rm":
                bd = bd100.multiply(plvBd).multiply(bd9);
                break;
            case "kt":
                bd = bd100.multiply(plvBd).multiply(bd95);
                break;
            case "hc":
                bd = bd100.multiply(plvBd).multiply(bd92);
                break;
        }
        int count = 0;
        for (int i = 0; i < plv2.length; i++) {
            if (plv2[i] == null || plv2[i].trim().isEmpty()) {
                continue;
            }
            BigDecimal bigDecimal = new BigDecimal(plv2[i]);
            if (bigDecimal.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            count++;
            BigDecimal plv2Bd = bigDecimal.subtract(bd1);
            bd = bd.subtract(bd10000.divide(plv2Bd, 2, RoundingMode.HALF_UP));
        }
        if (count == 0) {
            bd = BigDecimal.ZERO;
        }
        return bd.toString();
    }
}
